package com.github.cdisk.xtrans.component;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.github.cdisk.xtrans.annotiation.Attribute;
import com.github.cdisk.xtrans.annotiation.Component;
import com.github.cdisk.xtrans.component.utils.SqlStruct;
import com.github.cdisk.xtrans.connect.Db;
import com.github.cdisk.xtrans.core.BaseComponent;
import com.github.cdisk.xtrans.core.ConfigFile;
import com.github.cdisk.xtrans.core.GlobalVariables;
import com.github.cdisk.xtrans.exception.BuildException;
import com.github.cdisk.xtrans.exception.NoVariableNameException;

@Component(value="SQL脚本", icon="script.png", group="常用元件")
public class SqlScript extends BaseComponent {

	private static final Logger LOGGER = Logger.getLogger(SqlScript.class);

	/** 要执行的sql语句 */
	@Attribute(value="执行SQL语句", group="执行")
	protected String sql;


	@Override
	public void build(ConfigFile config, GlobalVariables variables) throws BuildException {
		super.build(config, variables);
		try {
			sql = variables.replaceVariables(sql); // 替换变量
		} catch (NoVariableNameException e) {
			throw new BuildException(this.getClass().getSimpleName() + "(" +  this.id + ")" + e.getMessage());
		}
		if (StringUtils.isEmpty(sql)) {
			throw new BuildException(this.getClass().getSimpleName() + "(" +  this.id + ")未找到语句[sql]内容。");
		}
		if (connect == null) {
			throw new BuildException(this.getClass().getSimpleName() + "(" +  this.id + ")没有指定数据库连接[connect]。");
		}
	}

	@Override
	public int execute(Map<String, Object> input) {

		/* 向下传递使用的map，为了在下层操作map时不影响上层，复制一个map */
		Map<String, Object> __map = new HashMap<String, Object>();
		__map.putAll(input);
		try {
			Db db = this.connect.getDb();
			db.open();

			/* 执行SQL脚本 */
			SqlStruct struct = new SqlStruct(this.sql, input);
			boolean called = db.executeCall(struct.sql, struct.param); // 执行SQL

			if (called) {
				/* 执行成功处理 */
				if (this.success != null) {
					this.success.execute(__map);
					__map.clear();
				}
				LOGGER.info("执行SQL:" + this.id + ", 执行成功.");
			} else {
				/* 执行失败处理 */
				if (this.failed != null) {
					this.failed.execute(__map);
					__map.clear();
				}
				LOGGER.info("执行SQL:" + this.id + ", 执行失败.");
			}
		} catch (SQLException e) {
			e.printStackTrace();
			/* 执行错误处理 */
			if (this.error != null) {
				__map.put("$errorCode", e.getErrorCode());
				__map.put("$errorMessage", e.getMessage());
				this.error.execute(input);
			}
			LOGGER.info("执行SQL:" + this.id + ", 执行错误, errorCode:" + e.getErrorCode() + ", errorMessage:" + e.getMessage());
			return EXECUTE_ERROR;
		}

		return EXECUTE_SUCCESS;
	}

	public String getSql() {
		return sql;
	}

	public void setSql(String sql) {
		this.sql = sql;
	}

}
